#include "stdafx.h"
#include "Home.h"
Home::Home()
{
	m_nHomeId = 0;
	m_nHomeVersion = 0;
	m_nCharId = 0;
	m_nRace = 0;
	m_nGender = 0;
	m_strCharName = "";
	m_nLevel = 0;
	m_stMapId = MapId();
	m_nTimerSyncHomeInfoToData = 0;
	LOGGER_INFO("Home:%p,m_nHomeId:%d",this,m_nHomeId);
}

Home::Home(HomeId nHomeId)
{
	//Home();
	m_nHomeId = 0;
	m_nHomeVersion = 0;
	m_nCharId = 0;
	m_nRace = 0;
	m_nGender = 0;
	m_strCharName = "";
	m_nLevel = 0;
	m_stMapId = MapId();
	m_nTimerSyncHomeInfoToData = 0;
	LOGGER_INFO("Home(HomeId nHomeId):%p,m_nHomeId:%d",this,m_nHomeId);
}
Home::~Home()
{
	DestroyTimer(m_nTimerSyncHomeInfoToData);
	LOGGER_INFO("~Home:%p,m_nHomeId:%d",this,m_nHomeId);
}
void Home::OnTimerSyncHomeInfoToData(UInt32 nTimerId)
{
	if(m_nTimerSyncHomeInfoToData != nTimerId)
	{
		LOGGER_ERROR("OnTimerSyncHomeInfoToData,m_nTimerSyncHomeInfoToData:%d,nTimerId:%d",m_nTimerSyncHomeInfoToData,nTimerId);
		DestroyTimer(nTimerId);
	}
	DestroyTimer(m_nTimerSyncHomeInfoToData);
	SyncHomeInfoToData();
}
void Home::SyncHomeInfoToData()
{
	Player* pPlayer = singleton<PlayerManager>::instance().GetByCharId(m_nCharId);
	if (pPlayer != NULL)
	{
		pPlayer->m_stCharHomeInfo = m_stHomeInfo;
	}
	PacketEncoder encoder;
	encoder.AddItem(Int32(0));
	encoder.AddItem(Int32(1301));

	encoder.AddItem(m_nCharId);
	DataBlock blkInfo;
	blkInfo.AppendData(&m_stHomeInfo,sizeof(m_stHomeInfo));
	encoder.AddItem(blkInfo);
	SendPacketToData(encoder);
}
void Home::SetHomeInfo(CharHomeInfo& info)
{
	m_stHomeInfo = info;
	m_nHomeVersion++;
}

void Home::SendPacketToAll(PacketEncoder& encoder)
{
	/*for (Int32 i = 0; i < m_stHomeInfo.m_nMembersSize; i++)
	{
		Player* pPlayer = singleton<PlayerManager>::instance().GetByCharId(m_stHomeInfo.m_arMembers[i].m_nCharId);
		if (pPlayer != NULL)
		{
			pPlayer->SendPacketToPlayer(encoder);
		}
	}*/
}
void Home::sendHomeBuildings(PlayerId stPlayerId)
{
	PacketEncoder encoder;
	encoder.AddItem(Int32(0));
	encoder.AddItem(Int32(1301));
	encoder.AddItem(Int32(m_nCharId));
	bool bNeedSync = false;
	encoder.AddItem(Int32(MAX_HOME_BUILDINGS_SIZE));
	for (Int32 i = 0; i < MAX_HOME_BUILDINGS_SIZE; i++)
	{
		CharHomeInfo::BuildingInfo& info = m_stHomeInfo.m_arBuildings[i];
		//if(info.m_nCSVId == 0 && info.m_nCSVId < 14)
		//	info.m_nCSVId = i + 1;
		encoder.AddItem(info.m_nCSVId);
		info.m_nInnerId = i+1;
		encoder.AddItem(info.m_nInnerId);
		encoder.AddItem(info.m_nState);
		encoder.AddItem(info.m_nLevel);
		if(info.m_nLevel == 0)
			continue;
		encoder.AddItem(info.m_nGainTime);
		encoder.AddItem(info.m_nGainStartTime == 0 ? 0 : Int32(time(NULL)) - info.m_nGainStartTime);
		if(info.m_nState == HOME_BUILDING_STATE_LEVELUP && info.m_nLevelupTime != 0 && info.m_nLevelupStartTime != 0 && Int32(time(NULL)) - info.m_nLevelupStartTime >= info.m_nLevelupTime)
		{
			info.m_nLevelupStartTime = 0;
			info.m_nLevelupTime = 0;
			info.m_nLevel += 1;
			info.setStateNormal();
			bNeedSync = true;
		}

		if(info.m_nState == HOME_BUILDING_STATE_NORMAL && info.m_nGainTime <= 0)
		{
			info.setStateNormal();
			bNeedSync = true;
		}
		encoder.AddItem(info.m_nLevelupTime);
		encoder.AddItem(info.m_nLevelupStartTime == 0 ? 0 : Int32(time(NULL)) - info.m_nLevelupStartTime);
		encoder.AddItem(info.m_nLevelupReqairWood);
		encoder.AddItem(info.m_nLevelupReqairFood);

		encoder.AddItem(info.m_nGuardType);
		encoder.AddItem(info.m_nGuardInnerId);
		encodeGuard(info.m_nGuardType,info.m_nGuardInnerId,encoder);

		encoder.AddItem(info.m_stCapture.m_nCharId);
		info.m_stCapture.m_szCharName[MAX_CHAR_NAME_SIZE - 1] = '\0';
		encoder.AddItem(info.m_stCapture.m_szCharName);
		encoder.AddItem(info.m_stCapture.m_nRace);
		encoder.AddItem(info.m_stCapture.m_nGender);
		encoder.AddItem(info.m_stCapture.m_nLevel);
		encoder.AddItem(info.m_nCaptureTime);
	}
	if(stPlayerId == PlayerId())
	{
		Map* pMap = singleton<MapManager>::instance().Get(m_stMapId);
		if (pMap != NULL)
		{
			pMap->SendPacketToAll(encoder);
		}
	}
	else
		SendPacket(stPlayerId.nSocketId,stPlayerId.nSocketIdOnGate,encoder);
	if (bNeedSync)
		PrepareSyncHomeInfoToData();

}

void Home::sendHomeBuildings(Int32 nInnerId,PlayerId stPlayerId)
{
	if(nInnerId <= 0 || nInnerId > MAX_HOME_BUILDINGS_SIZE)
		return;
	PacketEncoder encoder;
	encoder.AddItem(Int32(0));
	encoder.AddItem(Int32(1301));
	encoder.AddItem(Int32(m_nCharId));

	encoder.AddItem(Int32(1));

	CharHomeInfo::BuildingInfo& info = m_stHomeInfo.m_arBuildings[nInnerId-1];
	if(info.m_nInnerId != nInnerId)
		return;
	encoder.AddItem(info.m_nCSVId);
	encoder.AddItem(info.m_nInnerId);
	encoder.AddItem(info.m_nState);
	encoder.AddItem(info.m_nLevel);
	bool bNeedSync = false;
	if(info.m_nLevel != 0)
	{
		encoder.AddItem(info.m_nGainTime);
		encoder.AddItem(info.m_nGainStartTime == 0 ? 0 : Int32(time(NULL)) - info.m_nGainStartTime);

		if(info.m_nState == HOME_BUILDING_STATE_LEVELUP && info.m_nLevelupTime != 0 && info.m_nLevelupStartTime != 0 && Int32(time(NULL)) - info.m_nLevelupStartTime >= info.m_nLevelupTime)
		{
			info.m_nLevelupStartTime = 0;
			info.m_nLevelupTime = 0;
			info.m_nLevel += 1;
			info.setStateNormal();
			bNeedSync = true;
		}

		if(info.m_nState == HOME_BUILDING_STATE_NORMAL && info.m_nGainTime <= 0)
		{
			info.setStateNormal();
			bNeedSync = true;
		}

		encoder.AddItem(info.m_nLevelupTime);
		encoder.AddItem(info.m_nLevelupStartTime == 0 ? 0 : Int32(time(NULL)) - info.m_nLevelupStartTime);
		encoder.AddItem(info.m_nLevelupReqairWood);
		encoder.AddItem(info.m_nLevelupReqairFood);

		encoder.AddItem(info.m_nGuardType);
		encoder.AddItem(info.m_nGuardInnerId);
		encodeGuard(info.m_nGuardType,info.m_nGuardInnerId,encoder);

		encoder.AddItem(info.m_stCapture.m_nCharId);
		info.m_stCapture.m_szCharName[MAX_CHAR_NAME_SIZE - 1] = '\0';
		encoder.AddItem(info.m_stCapture.m_szCharName);
		encoder.AddItem(info.m_stCapture.m_nRace);
		encoder.AddItem(info.m_stCapture.m_nGender);
		encoder.AddItem(info.m_stCapture.m_nLevel);
		encoder.AddItem(info.m_nCaptureTime);
	}
	if(stPlayerId == PlayerId())
	{
		Map* pMap = singleton<MapManager>::instance().Get(m_stMapId);
		if (pMap != NULL)
		{
			pMap->SendPacketToAll(encoder);
		}
	}
	else
		SendPacket(stPlayerId.nSocketId,stPlayerId.nSocketIdOnGate,encoder);

	if (bNeedSync) PrepareSyncHomeInfoToData();
}

void Home::sendHomePetBuyableItems(PlayerId stPlayerId)
{
	PacketEncoder encoder;
	encoder.AddItem(Int32(0));
	encoder.AddItem(Int32(1309));
	encoder.AddItem(Int32(m_nCharId));
	bool bNeedSync = false;
	encoder.AddItem(Int32(MAX_HOME_PET_BUYABLE_EGG_SIZE));
	for (Int32 i = 0; i < MAX_HOME_PET_BUYABLE_EGG_SIZE; i++)
	{
		CharHomeInfo::PetBuyableItem& info = m_stHomeInfo.m_arBuyableEggs[i];
		if(info.m_nItemId == 0){bNeedSync = true;refreshHomePetBuyableEgg(i);}
		encoder.AddItem(info.m_nItemId);
		encoder.AddItem(info.m_nPrice);
		encoder.AddItem(info.m_tRefreshTime);
	}

	encoder.AddItem(Int32(MAX_HOME_PET_BUYABLE_BOOK_SIZE));
	for (Int32 i = 0; i < MAX_HOME_PET_BUYABLE_BOOK_SIZE; i++)
	{
		CharHomeInfo::PetBuyableItem& info = m_stHomeInfo.m_arBuyableBooks[i];
		if(info.m_nItemId == 0){bNeedSync = true;refreshHomePetBuyableBook(i);}
		encoder.AddItem(info.m_nItemId);
		encoder.AddItem(info.m_nPrice);
		encoder.AddItem(info.m_tRefreshTime);
	}

	SendPacket(stPlayerId.nSocketId,stPlayerId.nSocketIdOnGate,encoder);
	if (bNeedSync) PrepareSyncHomeInfoToData();
}
void Home::encodeGuard(Int32 nGuardType,Int32 nGuardInnerId,PacketEncoder& encoder)
{
	//encoder.AddItem(nGuardType);
	//encoder.AddItem(nGuardInnerId);
	if(nGuardType == PARTNER_TYPE_PET)
	{
		PetInfo* pPetInfo = PlayerSlave::getPetInfoByInnerId(m_stCharInfo,nGuardInnerId);
		if (pPetInfo == NULL)
		{
			encoder.AddItem(Int32(0));
		}
		else
		{
			encoder.AddItem(pPetInfo->m_nInnerId);
			encoder.AddItem(pPetInfo->m_szCharName);
			encoder.AddItem(pPetInfo->m_nImageId);
		}
	}
	if(nGuardType == PARTNER_TYPE_LOVER)
	{
		LoverInfo& info = m_stCharInfo.m_stLoverInfo;
		if (info.m_nCharId == 0)
		{
			encoder.AddItem(Int32(0));
		}
		else
		{
			encoder.AddItem(info.m_nCharId);
			encoder.AddItem(info.m_nCharId);
			info.m_szCharName[MAX_CHAR_NAME_SIZE - 1] = '\0';
			encoder.AddItem(info.m_szCharName);
			encoder.AddItem(info.m_nRace);
			encoder.AddItem(info.m_nGender);
			encoder.AddItem(Int32(MAX_ITEM_EQUIP_SIZE));
			for (Int32 i = 0; i < MAX_ITEM_EQUIP_SIZE; i++)
			{
				encoder.AddItem(Int32(info.m_arEquipImageId[i]));
			}
		}
	}
	if(nGuardType == PARTNER_TYPE_SLAVE)
	{
		SlaveInfo *pSlaveInfo = PlayerSlave::getSlaveInfoByInnerId(m_stCharInfo,nGuardInnerId);
		if (pSlaveInfo == NULL)
		{
			encoder.AddItem(Int32(0));
		}
		else
		{
			SlaveInfo& info = *pSlaveInfo;

			encoder.AddItem(info.m_nInnerId);
			encoder.AddItem(info.m_nCharId);
			info.m_szCharName[MAX_CHAR_NAME_SIZE - 1] = '\0';
			encoder.AddItem(info.m_szCharName);
			encoder.AddItem(info.m_nRace);
			encoder.AddItem(info.m_nGender);
			encoder.AddItem(Int32(MAX_ITEM_EQUIP_SIZE));
			for (Int32 i = 0; i < MAX_ITEM_EQUIP_SIZE; i++)
			{
				encoder.AddItem(Int32(info.m_arEquipImageId[i]));
			}
		}
	}
}

CharHomeInfo::BuildingInfo* Home::getHomeBuildingByInnerId(Int32 nInnerId)
{
	for (Int32 i = 0; i < MAX_HOME_BUILDINGS_SIZE; i++)
	{
		m_stHomeInfo.m_arBuildings[i].m_nInnerId = i+1;
		if(m_stHomeInfo.m_arBuildings[i].m_nInnerId == nInnerId)
			return &(m_stHomeInfo.m_arBuildings[i]);
	}
	return NULL;
}

void Home::refreshHomePetBuyableEgg(Int32 nIndex)
{
	if (nIndex >= MAX_HOME_PET_BUYABLE_EGG_SIZE)
		return;
	HomePetEggCSVInfo* pHomePetEggCSVInfo = singleton<HomeManager>::instance().GetRandomHomePetEggCSVInfo();
	if (pHomePetEggCSVInfo == NULL)
	{
		return;
	}
	CharHomeInfo::PetBuyableItem& info = m_stHomeInfo.m_arBuyableEggs[nIndex];
	info.m_nItemId = pHomePetEggCSVInfo->item_id;
	info.m_nPrice = singleton<GameServer>::instance().GetValueMaxMinBetween(pHomePetEggCSVInfo->price_max,pHomePetEggCSVInfo->price_min);
	info.m_tRefreshTime = Int32(time(NULL));
}
void Home::refreshHomePetBuyableBook(Int32 nIndex)
{
	if (nIndex >= MAX_HOME_PET_BUYABLE_BOOK_SIZE)
		return;

	HomePetBookCSVInfo* pHomePetBookCSVInfo = singleton<HomeManager>::instance().GetRandomHomePetBookCSVInfo();
	if (pHomePetBookCSVInfo == NULL)
	{
		return;
	}
	CharHomeInfo::PetBuyableItem& info = m_stHomeInfo.m_arBuyableBooks[nIndex];
	info.m_nItemId = pHomePetBookCSVInfo->item_id;
	info.m_nPrice = singleton<GameServer>::instance().GetValueMaxMinBetween(pHomePetBookCSVInfo->price_max,pHomePetBookCSVInfo->price_min);
	info.m_tRefreshTime = Int32(time(NULL));

}